<template>
	<view class="swiper-box">
		<swiper class="swiper" :indicator-dots="false" :autoplay="autoplay" :circular="circular" :interval="interval" :duration="duration" @change="handleChange">
			<swiper-item class="swiper-item" v-for="(item, index) in list" :key="index">
				<view class="swiper-item-content">
					<image class="swiper-item-content-img" :src="item.img" mode="aspectFill"></image>
					<text class="swiper-item-content-title"
					:style="{'font-size': titleSize + 'px', color: titleColor, top: titleTop + 'px', 'left': leftGap + 'px'}" ref="title">{{item.title}}</text>
					<text class="swiper-item-content-navigate"
					:style="{'font-size': buttonSize + 'px',
						'color': buttonColor,
						'border-color': buttonColor,
						'top': buttonTop ? buttonTop + 'px' : (Number(titleTop) + Number(titleSize) + 20) + 'px',
						'left': (Number(leftGap) - 10) + 'px'
					}" ref="navigate" @tap="handleButtonTap(index)">{{item.button || '查看详情'}} ➜</text>
				</view>
			</swiper-item>
		</swiper>
		<view class="swiper-box-dots"
		:style="{
			'justify-content': dotDock == 'right' ? 'flex-end' : dotDock == 'center' ?  'center' : 'flex-start',
			'bottom': dotBottom + 'px',
			'left': leftGap + 'px',
			'right': rightGap + 'px'
		}">
			<view class="swiper-box-dot"
			:style="{
				'width': current == index ? dotActiveWidth + 'px' : '6px',
				'background-color': dotColor
			}"
			v-for="(item, index) in list" :key="index">
				<view ref="dot" class="swiper-box-dot-interval" :style="{'background-color': current == index ? dotActiveColor : dotColor}"></view>
			</view>
		</view>
	</view>
</template>

<script>
	const animation = uni.requireNativePlugin('animation')
	export default {
		props: {
			list: {
				type: Array,
				default: () => []
			},
			autoplay: {
				type: Boolean,
				default: true
			},
			circular: {
				type: Boolean,
				default: true
			},
			interval: {
				type: [Number, String],
				default: 3000
			},
			duration: {
				type: [Number, String],
				default: 1000
			},
			textAnimationDuration: {
				type: [Number, String],
				default: 300
			},
			titleSize: {
				type: [Number, String],
				default: 20
			},
			titleTop: {
				type: [Number, String],
				default: 30
			},
			titleColor: {
				type: String,
				default: '#fff'
			},
			buttonColor: {
				type: String,
				default: '#fff'
			},
			buttonSize: {
				type: [Number, String],
				default: 12
			},
			buttonTop: {
				type: [Number, String],
				default: ''
			},
			dotBottom: {
				type: [Number, String],
				default: 10
			},
			dotDock: {
				type: String,
				default: 'left'
			},
			dotColor: {
				type: String,
				default: '#999'
			},
			dotActiveWidth: {
				type: [Number, String],
				default: 30
			},
			dotActiveColor: {
				type: String,
				default: '#fff'
			},
			leftGap: {
				type: [Number, String],
				default: 20
			},
			rightGap: {
				type: [Number, String],
				default: 20
			}
		},
		data () {
			return {
				current: 0
			}
		},
		mounted() {
			if ( this.list.length > 0 ) {
				this.handleChange({detail: {current: this.current}})
			}
		},
		methods: {
			handleChange (e) {
				this.current = e.detail.current
				const dot = this.$refs.dot[this.current]
				animation.transition(dot, {
				    styles: {
				        width: this.dotActiveWidth
				    },
				    duration: this.interval, //ms
					needLayout: false,
				    timingFunction: 'ease',
				    delay: 0 //ms
				}, () => {
					animation.transition(dot, {
					    styles: {
					        width: 0
					    },
					    duration: 0, //ms
						needLayout: true,
					    timingFunction: 'ease',
					    delay: 0 //ms
					})
				})
				const title = this.$refs.title[this.current]
				animation.transition(title, {
				    styles: {
				        opacity: 0,
						transform: 'translateY(0)',
				    },
				    duration: 0, //ms
					needLayout: false,
				    timingFunction: 'ease',
				    delay: 0 //ms
				}, () => {
					animation.transition(title, {
					    styles: {
					        opacity: 1,
							transform: 'translateY(10px)',
					    },
					    duration: this.textAnimationDuration, //ms
						needLayout: false,
					    timingFunction: 'ease',
					    delay: 0 //ms
					})
				})
				const navigate = this.$refs.navigate[this.current]
				animation.transition(navigate, {
				    styles: {
				        opacity: 0,
						transform: 'translateX(0)',
				    },
				    duration: 0, //ms
					needLayout: false,
				    timingFunction: 'ease',
				    delay: 0 //ms
				}, () => {
					animation.transition(navigate, {
					    styles: {
					        opacity: 1,
							transform: 'translateX(10px)',
					    },
					    duration: this.textAnimationDuration, //ms
						needLayout: false,
					    timingFunction: 'ease',
					    delay: this.textAnimationDuration //ms
					})
				})
			},
			handleButtonTap (index) {
				this.$emit('button-click', {current: index, detail: this.list[index]})
			}
		},
		watch: {
			list (newVal) {
				if ( newVal.length > 0 ) {
					this.handleChange({detail: {current: this.current}})
				}
			}
		}
	}
</script>

<style>
	.swiper-box {
		position: relative;
		display: flex;
		flex-direction: column;
	}
	.swiper {
		flex: 1;
		display: flex;
		flex-direction: column;
	}
	.swiper-item {
		flex: 1;
	}
	.swiper-item-content {
		position: relative;
		flex: 1;
		display: flex;
		flex-direction: column;
	}
	.swiper-item-content-img {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	.swiper-item-content-title {
		position: absolute;
		color: #fff;
		font-weight: bold;
		opacity: 0;
	}
	.swiper-item-content-navigate {
		position: absolute;
		color: #fff;
		opacity: 0;
		background-color: rgba(0,0,0,.2);
		border-radius: 3px;
		border-width: 1px;
		border-style: solid;
		padding: 5px 10px;
	}
	.swiper-item-content-navigate:active {
		background-color: rgba(0,0,0,.6);
	}
	.swiper-box-dots {
		display: flex;
		flex-direction: row;
		position: absolute;
	}
	.swiper-box-dot {
		width: 6px;
		height: 4px;
		border-radius: 4px;
		margin-right: 4px;
		position: relative;
		overflow: hidden;
	}
	.swiper-box-dot-interval {
		position: absolute;
		top: 0;
		left: 0;
		bottom: 0;
		border-radius: 4px;
	}
</style>